Unlike K-means algorithm, each data object is not the member of only one cluster but is the member of all clusters with varying degrees of memberhip between 0 and 1.
In our case , each data object belong to ONLY one cellular component nuclear, cytoplasm or membrane.
Conclusion: 1 - fcm and pfcm takes a lot of time if we use high image resolution 2 - k-means method seems to be more suitable.
im <- readImage("basales.jpg")
dim(im)
## [1] 1024 768 3
plot(im) # raster method means within R
## I. reduce the size of image
# scale to a specific width and height
#ims <- resize(im, w = 200, h = 100)
# II. scale by 50%; the height is determined automatically so that
# the aspect ratio is preserved
ims <- resize(im, dim(im)[1]/8)
ims
## Image
## colorMode : Color
## storage.mode : double
## dim : 128 96 3
## frames.total : 3
## frames.render: 1
##
## imageData(object)[1:5,1:6,1]
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.8235294 0.8225490 0.8127451 0.7823529 0.7833333 0.7980392
## [2,] 0.8137255 0.7970588 0.7843137 0.7656863 0.7156863 0.7882353
## [3,] 0.8196078 0.7460784 0.7833333 0.7725490 0.8196078 0.8343137
## [4,] 0.7872549 0.8362745 0.8764706 0.8313725 0.8843137 0.8382353
## [5,] 0.7921569 0.8725490 0.8980392 0.8500000 0.8784314 0.8774510
plot(ims)
# reshape image into a data frame
df = data.frame(
red = matrix(ims[,,1], ncol=1),
green = matrix(ims[,,2], ncol=1),
blue = matrix(ims[,,3], ncol=1)
)
str(df)
## 'data.frame': 12288 obs. of 3 variables:
## $ red : num 0.824 0.814 0.82 0.787 0.792 ...
## $ green: num 0.801 0.785 0.768 0.725 0.696 ...
## $ blue : num 0.788 0.799 0.775 0.773 0.759 ...
# Possibilistic Fuzzy C-Means Clustering Algorithm
## this run takes a lot of time even I reduce the size of image by 4
# res.pfcm <- ppclust::pfcm(df, centers=5)
# a numeric matrix containing the final cluster prototypes.
# res.pfcm$v
# red green blue
# Cluster 1 0.8420613 0.6191732 0.6977437
# Cluster 2 0.8182934 0.4876898 0.5617337
# Cluster 3 0.8720549 0.7644502 0.7797300
# Cluster 4 0.8355903 0.5195514 0.6029807
# Cluster 5 0.6927238 0.4240574 0.5330456
# a numeric matrix containing the typicality degrees of the data objects.
# head(res.pfcm$t)
# Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5
# 1 0.1288446 0.02401000 0.5443269 0.04291962 0.02055977
# 2 0.1372704 0.02475138 0.5163443 0.04446920 0.02134524
# 3 0.1778028 0.02888067 0.6170897 0.05291714 0.02388038
# 4 0.2379715 0.03496650 0.3370548 0.06518729 0.02919441
# 5 0.3363520 0.04244848 0.2810300 0.08164521 0.03373603
# 6 0.2753612 0.04541603 0.1528285 0.08426691 0.03965113
# a numeric matrix containing the distances of objects to the final cluster proto- types
# head(res.pfcm$d)
# Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5
# 1 0.04158602 0.14948141 0.003761511 0.11366701 0.2243028
# 2 0.03865589 0.14489382 0.004208872 0.10952852 0.2158755
# 3 0.02844168 0.12365149 0.002788159 0.09122913 0.1924584
# 4 0.01969538 0.10149022 0.008837837 0.07309768 0.1565697
# 5 0.01213561 0.08295336 0.011495473 0.05733525 0.1348580
# 6 0.01618590 0.07729278 0.024907817 0.05539285 0.1140377
# a numeric vector containing the cluster labels found by defuzzifying the typicality degrees of the objects.
# res.pfcm$cluster[1:20]
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# 3 3 3 3 1 1 1 1 3 1 1 4 4 4 4 4 2 2 5 5
#unique(res.pfcm$cluster)
#[1] 3 1 4 2 5
# a numeric vector for the number of objects in the clusters.
# res.pfcm$csize
# 1 2 3 4 5
# 2892 2028 2610 2174 2584
# df$label = res.pfcm$cluster
### Replace the color of each pixel in the image with the mean
### R,G, and B values of the cluster in which the pixel resides:
# # get the coloring
# colors = data.frame(
# label = 1:nrow(res.pfcm$centers),
# R = res.pfcm$v[,"red"],
# G = res.pfcm$v[,"green"],
# B = res.pfcm$v[,"blue"]
# )
#
# # merge color codes on to df
# # IMPORTANT: we must maintain the original order of the df after the merge!
#
# df$order <- 1:nrow(df)
# df <- merge(df, colors)
#
#
# # reorder the matrix (image)
# df <- df[order(df$order),]
# df$order = NULL
#
# # get mean color channel values for each row of the df.
# R <- matrix(df$R, nrow=dim(ims)[1])
# G <- matrix(df$G, nrow=dim(ims)[1])
# B <- matrix(df$B, nrow=dim(ims)[1])
#
# # reconstitute the segmented image in the same shape as the input image
# im.segmented <- array(dim=dim(ims))
# im.segmented[,,1] = R
# im.segmented[,,2] = G
# im.segmented[,,3] = B
#
# im.segmented <- EBImage::Image(im.segmented, colormode=Color)
#
# plot(im.segmented)
im <- readImage("basales.jpg")
dim(im)
## [1] 1024 768 3
# II. scale by 50%; the height is determined automatically so that
# the aspect ratio is preserved
ims <- resize(im, dim(im)[1]/8)
plot(ims)
# reshape image into a data frame
# df = data.frame(
# red = matrix(ims[,,1], ncol=1),
# green = matrix(ims[,,2], ncol=1),
# blue = matrix(ims[,,3], ncol=1)
# )
# #res.fcm <- ppclust::fcm(df, centers = 5)
# str(res.fcm)
# List of 17
# $ u : num [1:12288, 1:5] 0.126 0.173 0.234 0.541 0.726 ...
# ..- attr(*, "dimnames")=List of 2
# .. ..$ : chr [1:12288] "1" "2" "3" "4" ...
# .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
# $ v : num [1:5, 1:3] 0.837 0.879 0.677 0.818 0.839 ...
# ..- attr(*, "dimnames")=List of 2
# .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
# .. ..$ : chr [1:3] "red" "green" "blue"
# $ v0 : num [1:5, 1:3] 0.719 0.908 0.72 0.839 0.776 ...
# ..- attr(*, "dimnames")=List of 2
# .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
# .. ..$ : chr [1:3] "red" "green" "blue"
# $ d : num [1:12288, 1:5] 0.02124 0.01897 0.0122 0.00741 0.00357 ...
# ..- attr(*, "dimnames")=List of 2
# .. ..$ : chr [1:12288] "1" "2" "3" "4" ...
# .. ..$ : chr [1:5] "Cluster 1" "Cluster 2" "Cluster 3" "Cluster 4" ...
# $ x : num [1:12288, 1:3] 0.824 0.814 0.82 0.787 0.792 ...
# ..- attr(*, "dimnames")=List of 2
# .. ..$ : chr [1:12288] "1" "2" "3" "4" ...
# .. ..$ : chr [1:3] "red" "green" "blue"
# $ cluster : Named int [1:12288] 2 2 2 1 1 1 1 1 1 1 ...
# ..- attr(*, "names")= chr [1:12288] "1" "2" "3" "4" ...
# $ csize : Named num [1:5] 2378 2062 2382 3032 2434
# ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
# $ sumsqrs :List of 4
# ..$ between.ss : num 372
# ..$ within.ss : Named num [1:5] 16.28 8.79 18.12 8.58 11.8
# .. ..- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
# ..$ tot.within.ss: num 63.6
# ..$ tot.ss : num 436
# $ k : num 5
# $ m : num 2
# $ iter : num 107
# $ best.start: int 1
# $ func.val : num 34.5
# $ comp.time : num 177
# $ inpargs :List of 8
# ..$ iter.max: int 1000
# ..$ con.val : num 1e-09
# ..$ dmetric : chr "sqeuclidean"
# ..$ alginitv: chr "kmpp"
# ..$ alginitu: chr "imembrand"
# ..$ fixcent : logi FALSE
# ..$ fixmemb : logi FALSE
# ..$ stand : logi FALSE
# $ algorithm : chr "FCM"
# $ call : language ppclust::fcm(x = df, centers = 5)
# - attr(*, "class")= chr "ppclust"